/*****************************************
 This file is part of the Dynamo UI Toolkit
 Copyright (c) Dynamo Studios 2008

 *** NOTE ***
 Permission is hereby granted to execute this file as a
 web service under the terms of the license agreement.

 See LICENSE.txt, in the system folder.

 All other rights, other than those expressed in the license
 document, are reserved.

 ****************************************/
 
/*
	Script: Editor Library
	Provides widgets for common editing tasks on the Client Side.
	
	Author:
		Sean Micklethwaite
		
	Version:
		0.1 (Alvin)
 */

/*
 * Class: UiForm
 * Represents all 'input' and 'editor' forms in the CMS.
 * Provides AJAX capabilities for asynchronous submission
 * of the form.
 */
var UiForm = new Class({
	form: null,
	options: Object(),
	stdArgs: null,
	
	initialize: function(frm){
		this.form = frm;
		console.log(frm.id);
		if(!$defined(frm.recvOptions)){
			
			//
			// We are standalone. Get the data from the parent form.
			//
			
			this.options.ajaxOutput = new Choqolate.Base.AjaxOutput(this.form);
			this.stdArgs = ajaxRq.GetQueryArgs(frm.getProperty('action'));
			this.options.ajaxOutput.id = $E("meta[name=objectId]")
				? $E("meta[name=objectId]").content : -1;
			
		}else{
		
			this.options = frm.recvOptions;
			
			//
			// Dirty hack!!
			// Need to get the form's action address, which gets
			// vapourised when we add it inside another form.. 
			//
			
			tmp = new Element('div', {style: 'visibility: hidden'});
			tmp.setHTML(this.options.ajaxGenRq.response.text);
			f = tmp.getElement("form");
			this.stdArgs = ajaxRq.GetQueryArgs(f.getProperty('action'));
			
			if(this.options.onFormLoad)
				this.options.onFormLoad(this);
		};
	},
	
	rigSubmitButtons: function(btns, opts){
		// Default options
		if(!$defined(opts))
			opts = {};
		if(!$defined(opts.resultContainer))
			opts.resultContainer = this.form.getProperty('id');
		if(!$defined(opts.ajaxOutput))
			opts.ajaxOutput = this.options.ajaxOutput;
		if(!$defined(opts.onFormLoad))
			opts.onFormLoad = this.options.onFormLoad;
		
		btns.each(function(btn){
		 	btn.addEvent('click',function(e){
		 	 	new Event(e).stop();
				
				//
				// Scrape form data from input elements
				// Todo: more elements?
				//
				
				var postArgs = new Object();
				this.form.getElementsBySelector("input, textarea, select").each(
						function(fData){
					
					postArgs[fData.getProperty('name')]
						= fData.value;
				});
				
				var stdArgs = this.stdArgs;
				postArgs[btn.getProperty('name')] = 
					ieButtonHackValue(btn);
				stdArgs['$$ui-resultContainer']
					= opts.resultContainer;
				
				
				//
				// Create the request
				//
				
				rq = new AjaxPostRequest(postArgs, stdArgs,{
					raw: true,
					callback: this.onResponse.bind(this)
				});
				
				rq.output = opts.ajaxOutput;
				rq.onFormLoad = opts.onFormLoad;
				
				//
				// Rig the AjaxOutput, then send the request.
				//
				
				this.options.ajaxOutput.rig();
				ajaxRq.Dispatch(rq);
				
			}.bind(this));
		}.bind(this));
	},
	
	onResponse: function(rq){
		//
		// Check the object ID of the response corresponds to
		// what we currently have. If not, then replace the form.
		//
		
		if (rq.meta.resultContainer && (rq.meta.resultContainer != ''))
		{
			console.log(rq.meta.resultContainer);
			output = $(rq.meta.resultContainer);
			if (!$defined(output)) {
				
				//
				// Result container is not currently in the form, so
				// it must be a new element in the response. Set the
				// assigned result container ID to the expected ID, and
				// we are good to go.
				//
				
				this.fireEvent('onNewResultContainer', rq);
				
				rq.output.getOutput().setProperty('id', rq.meta.resultContainer);
				rq.output.receive(rq.request.response.text);
				rq.output.getOutput().recvOptions = {
			 		ajaxOutput: rq.output,
					ajaxGenRq: rq.request,
					onFormLoad: rq.onFormLoad
				};
				
			}else{
				
				output.ajaxOutput.receive(rq.request.response.text);
				output.recvOptions = {
			 		ajaxOutput: output.ajaxOutput,
					ajaxGenRq: rq.request,
					onFormLoad: rq.onFormLoad
				};
			}
			
			this.fireEvent('onUpdate', rq);
			
		}else{
			//
			// No resultContainer defined:
			// Display in dialog box
			//
			var overlay = new Choqolate.UI.Dialog("Title", {'modal': true, 'class' : 'UIDialog'}).addTo(Choqolate.ui);
			overlay.ajaxify();
			
			overlay.rig();
			overlay.receive(rq.request.response.text);
			
			overlay.getOutput().recvOptions = {
		 		ajaxOutput: overlay,
				ajaxGenRq: rq.request,
				onFormLoad: rq.onFormLoad
			};
		}
		
		rq.request.evalScripts();
	}
});
UiForm.implement(new Events);


/*	Class: UiEditor
	Not yet documented.
*/
var UiEditor = UiForm.extend({
	initialize: function(frm){
		this.parent(frm);
		
		//
		// Rig editor buttons. Each button results in a 
		// submission of the form, which will be made via
		// AJAX; the contents of this call will then be
		// put into our container.
		//
		
		this.rigSubmitButtons(this.form.getElements("button"));
	}
});


/*	
 * Class: UiPublisher
 * Client side representation of the object publisher widget.
 */
var UiPublisher = UiForm.extend({
	initialize: function(frm){
		this.parent(frm);
		this.rigSubmitButtons(this.form.getElements("button"));
	}
});


/*	
 * Class: UiManager
 * Not yet documented.
 */
var UiManager = UiForm.extend({
	form		: {},
	liveTable	: {},
	stdArgs		: {},
	ajaxRequest	: [],
	
	initialize: function(oMgr){
		if($defined(oMgr.recvOptions))
			oMgr.setHTML("Error: UiManager cannot be embedded");
		
		this.parent(oMgr);
		
		// Test LiveTable
		this.liveTable = new Choqolate.LiveTable(oMgr, {
			deleteFirstColumn: true,
			buttonCSS  : 'button',
			idColumnCSS: '.col-1'		
		}, {
			cancel: {'text': '', 'class': 'triplet close'},
			minimize: {'text': '', 'class': 'triplet minimize'},
			maximize: {'text': '', 'class': 'triplet maximize'},
		});
		
		this.liveTable.addEvent('onRowUpdate', function(row){
			// Rig the edit button
			this.rigButtons(row.dataRow.getElements('button[class^=buttonVal-edit]'));
		}.bind(this));
		
		this.stdArgs = ajaxRq.GetCurrentQueryArgs();
		
		this.rigEditButton();
		
		this.addEvent('onNewResultContainer', this.onNewResultContainer.bind(this));
		this.options.ajaxOutput.onFormLoad = this.onFormLoad.bind(this);
		
		// Rig the create new buttons
		this.rigSubmitButtons(this.form.getElements('button[class=buttonVal-create]'),{
			resultContainer: 'LiveRow-0',
			onFormLoad: this.onFormLoad.bind(this)
		});
		// Delete buttons
		this.rigSubmitButtons(this.form.getElements('button[class^=buttonVal-del-]'),{
			resultContainer: ''
		});
	},
	
	onNewResultContainer: function(rq){
		if ($defined(rq.meta.objectId)) {
			if ((rq.meta.objectId !== rq.output.id) &&
			(rq.output.id != 0)) {
			
				//
				// Add a row to the table for the container
				//
				
				output = this.liveTable.addRow(rq.meta.objectId);
				output.rig();
				output.onFormLoad = rq.output.onFormLoad;
				rq.output = output;
			}
			else {
			
				//
				// Keep the original container, but set its new ID
				//
				
				rq.output.id = rq.meta.objectId;
				rq.output.getOutput().id = rq.meta.resultContainer;
			};
			console.log(rq.meta.objectId);
			rq.output.table.fireEvent('onRowUpdate', rq.output);
		};
	},
	
	onUpdate: function(rq){
		data = {};
		if ($defined(rq.meta.objectId)) {
			data[0] = rq.meta.objectId;
			console.log("ID:"+rq.meta.objectId);
		};
		
		this.update(data);
	},
	
	onFormLoad: function(frm){
		console.log("form");
		frm.addEvent('onUpdate', this.onUpdate.bind(frm.options.ajaxOutput));
		frm.addEvent('onNewResultContainer', this.onNewResultContainer.bind(this));
	},
	
	rigEditButton: function(){
		this.rigButtons(this.form.getElements('button[class^=buttonVal-edit]'));
	},
	
	
	/*
	 * Function: rigButtons
	 * Rigs a collection of row-specific action buttons for use with the LiveTable.
	 * The results of the action will either be displayed in the LiveRow or a dialog
	 * box, depending on the response from the server.
	 * 
	 * Parameter:
	 * 	btns - collection of buttons to rig
	 */
	rigButtons: function(btns){		
		btns.each(function(btn, i){
		 	btn.addEvent('click',function(e){
		 	 	new Event(e).stop();
				
				//
				// Prep. for AJAX request
				//
				
				btn.row.rig();

				
				//
				// Start the request
				//
				
				var postArgs = new Object();
				var stdArgs = this.stdArgs;
				
				postArgs[btn.getProperty('name')]
					= ieButtonHackValue(btn);
				
				stdArgs['$$ui-resultContainer']
					= btn.row.getOutput().getProperty('id');
				
				// TODO: form data
				
				rq = new AjaxPostRequest(postArgs, stdArgs,{
					raw: true,
					callback: this.onResponse.bind(this)
				});
				
				rq.output = btn.row;
				rq.onFormLoad = this.onFormLoad.bind(this);
				
				ajaxRq.Dispatch(rq);
			}.bind(this));
			
		}.bind(this));
	}
});


/*	
 * Class: UiPublisher
 * Client side representation of the object publisher widget.
 */
var UiOwnershipEditor = UiForm.extend({
	initialize: function(frm){
		this.parent(frm);
		this.rigSubmitButtons(this.form.getElements("button"));
	}
});

